package com.mofang.ticketing.user.serve.merchant.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.mofang.ticketing.common.core.dto.PrimaryIdDTO;
import com.mofang.ticketing.common.core.enums.account.AccountTypeEnum;
import com.mofang.ticketing.common.core.enums.account.BelongEnum;
import com.mofang.ticketing.common.core.enums.merchant.MerchantTypeEnum;
import com.mofang.ticketing.common.core.exception.BizException;
import com.mofang.ticketing.common.core.util.CopyUtil;
import com.mofang.ticketing.common.security.util.SecurityUtil;
import com.mofang.ticketing.user.mapping.entity.MerchantInfoDO;
import com.mofang.ticketing.user.mapping.entity.SysUserDO;
import com.mofang.ticketing.user.mapping.mapper.MerchantInfoDOMapper;
import com.mofang.ticketing.user.mapping.mapper.SysUserDOMapper;
import com.mofang.ticketing.user.serve.account.dto.request.AccountUpdatePhoneReqDTO;
import com.mofang.ticketing.user.serve.account.mapper.AccountMapper;
import com.mofang.ticketing.user.serve.account.service.AuthService;
import com.mofang.ticketing.user.serve.account.service.MerchantAccountService;
import com.mofang.ticketing.user.serve.merchant.dto.request.MerchantAddReqDTO;
import com.mofang.ticketing.user.serve.merchant.dto.request.MerchantListPageReqDTO;
import com.mofang.ticketing.user.serve.merchant.dto.request.MerchantUpdateReqDTO;
import com.mofang.ticketing.user.serve.merchant.dto.response.MerchantDetailRespDTO;
import com.mofang.ticketing.user.serve.merchant.dto.response.MerchantListPageRespDTO;
import com.mofang.ticketing.user.serve.merchant.dto.response.MerchantSelectRespDTO;
import com.mofang.ticketing.user.serve.merchant.mapper.MerchantMapper;
import com.mofang.ticketing.user.serve.merchant.service.MerchantService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author LGC
 * @date 2023/3/15 16:50
 */
@Slf4j
@Service
public class MerchantServiceImpl implements MerchantService {
    @Resource
    private MerchantMapper merchantMapper;
    @Resource
    private MerchantInfoDOMapper merchantInfoDOMapper;
    @Resource
    private SysUserDOMapper sysUserDOMapper;
    @Resource
    private MerchantAccountService merchantAccountService;
    @Resource
    private AccountMapper accountMapper;
    @Resource
    private AuthService authService;

    @Override
    public MerchantDetailRespDTO merchantDetail(PrimaryIdDTO dto) {
        MerchantInfoDO merchantInfoDO = merchantInfoDOMapper.selectById(dto.getId());
        if (merchantInfoDO == null) {
            throw new BizException("商户不存在");
        }
        return CopyUtil.copy(merchantInfoDO, MerchantDetailRespDTO.class);
    }

    @Override
    public IPage<MerchantListPageRespDTO> merchantListPage(MerchantListPageReqDTO dto) {
        return merchantMapper.merchantListPage(dto.getPage().getPage(), dto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void merchantAdd(MerchantAddReqDTO dto) {
        Integer accountType = SecurityUtil.getAccountType();
        assert accountType != null;
        if (!accountType.equals(AccountTypeEnum.PLATFORM_ADMIN.getKey())) {
            throw new BizException("暂无权限创建商户");
        }
        Long count = new LambdaQueryChainWrapper<>(sysUserDOMapper)
                .eq(SysUserDO::getAccount, dto.getAdminAccount())
                .eq(SysUserDO::getBelong, BelongEnum.PLATFORM.getKey()).count();
        if (count > 0) {
            throw new BizException("该手机号已被平台注册使用");
        }
        Long userId = SecurityUtil.getUserId();
        // 创建商户
        MerchantInfoDO insertMerchantInfo = CopyUtil.copy(dto, MerchantInfoDO.class);
        insertMerchantInfo.setMerchantType(MerchantTypeEnum.SCENIC.getKey());
        insertMerchantInfo.setCreateUserId(userId);
        insertMerchantInfo.setCreateTime(new Date());
        insertMerchantInfo.setUpdateUserId(userId);
        insertMerchantInfo.setUpdateTime(new Date());
        insertMerchantInfo.setRevision(0);
        merchantInfoDOMapper.insert(insertMerchantInfo);
        // 初始化商户管理员
        authService.initMerchantAdminAccount(dto.getAdminUsername(), dto.getAdminAccount(), insertMerchantInfo.getId(), userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void merchantUpdate(MerchantUpdateReqDTO dto) {
        Integer accountType = SecurityUtil.getAccountType();
        assert accountType != null;
        if (!accountType.equals(AccountTypeEnum.PLATFORM_ADMIN.getKey())) {
            throw new BizException("暂无权限修改商户");
        }
        MerchantInfoDO merchant = merchantInfoDOMapper.selectById(dto.getId());
        if (merchant == null) {
            throw new BizException("商户不存在");
        }
        Long userId = SecurityUtil.getUserId();
        String oldPhone = merchant.getAdminAccount();
        String newPhone = dto.getAdminAccount();
        // 商户管理员账号发生改变
        if (!dto.getAdminAccount().equals(merchant.getAdminAccount())) {
            Long count = new LambdaQueryChainWrapper<>(sysUserDOMapper)
                    .eq(SysUserDO::getAccount, newPhone)
                    .eq(SysUserDO::getBelong, BelongEnum.PLATFORM.getKey()).count();
            if (count > 0) {
                throw new BizException("该手机号已被平台注册使用");
            }
            // 更新账号（手机号）
            SysUserDO merchantAdminAccount = accountMapper.selectUserByAccountAndBelong(merchant.getAdminAccount(), BelongEnum.MERCHANT.getKey());
            merchantAccountService.merchantAccountUpdatePhone(
                    new AccountUpdatePhoneReqDTO(oldPhone, newPhone, newPhone),
                    merchantAdminAccount.getId()
            );
        }

        BeanUtil.copyProperties(dto, merchant);
        merchant.setUpdateTime(new Date());
        merchant.setUpdateUserId(userId);
        merchantInfoDOMapper.updateById(merchant);
    }

    @Override
    public List<MerchantSelectRespDTO> merchantSelect() {
        return merchantMapper.merchantSelect();
    }
}
